package com.fivestyle.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fivestyle.common.result.R;
import com.fivestyle.common.tool.JwtUtils;
import com.fivestyle.common.tool.MD5;
import com.fivestyle.entity.User;
import com.fivestyle.entity.vo.RegisterVo;
import com.fivestyle.mapper.UserMapper;
import com.fivestyle.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;

import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import java.text.DecimalFormat;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 张代钊
 * @since 2021-08-04
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String from;


    @Transactional
    @Override
    public R register(RegisterVo registerVo) {
        //获取注册的数据
        String code = registerVo.getCode(); //验证码
        String mobile = registerVo.getPhone(); //手机号
        String nickname = registerVo.getName(); //昵称
        String password = registerVo.getPassword(); //密码
        String email = registerVo.getEmail(); //邮箱
        Integer sex = registerVo.getSex();

        //非空判断
        if(StringUtils.isEmpty(mobile) || StringUtils.isEmpty(password)
                || StringUtils.isEmpty(code) || StringUtils.isEmpty(nickname)|| StringUtils.isEmpty(sex)) {
            return R.error().message("有空信息，注册失败！");
        }
        //判断验证码
        //获取redis验证码
        String redisCode = redisTemplate.opsForValue().get(email);
        System.out.println("浏览器传来的code："+code+"     redis上面保存的code："+redisCode);
        if(!code.equals(redisCode)) {
            return R.error().message("验证码错误，注册失败！");
        }

        //判断手机号是否重复，表里面存在相同手机号或邮箱不进行添加
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",mobile).or().eq("email",email);
        Integer count = baseMapper.selectCount(wrapper);
        if(count > 0) {
            return R.error().message("该邮箱或者手机号已被注册，注册失败！");
        }

        //数据添加数据库中
        if (StringUtils.isEmpty(registerVo.getAvator()))
            registerVo.setAvator("https://dioda.oss-cn-chengdu.aliyuncs.com/2021/06/16/2dac0368d2a043b9abd617a923ef540dfile.png");

        try {
            User member = new User();
            BeanUtils.copyProperties(registerVo,member);
            member.setPassword(MD5.encrypt(member.getPassword()));
            baseMapper.insert(member);
            return R.ok().message("用户注册成功");
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error().message("用户注册失败！");

        }
    }

    @Override
    public R sendMail(String email) {
        if (!StringUtils.isEmpty(redisTemplate.opsForValue().get(email))) {
            return R.ok();
        }
        String code = new DecimalFormat("000000")
                .format(new Random().nextInt(1000000));

        if (this.sendQQMail(email,code)) {
            redisTemplate.opsForValue().set(email,code,3, TimeUnit.MINUTES);
            return R.ok().message("邮箱发送成功，验证码为"+code);
        }else {
            return R.error().message("邮箱发送验证码失败！");
        }
    }

    @Override
    public R login(User member) {
        //获取登录手机号和密码
        String mobile = member.getPhone();
        String email = member.getEmail();
        String password = member.getPassword();

        //手机号或者邮箱和密码非空判断
        if((StringUtils.isEmpty(mobile) || StringUtils.isEmpty(password))
                && (StringUtils.isEmpty(email) || StringUtils.isEmpty(password))) {
            return R.error().message("邮箱或者电话或者密码为空！");
        }

        //判断手机号是否正确
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",mobile).or().eq("email",email);
        User mobileMember = baseMapper.selectOne(wrapper);
        //判断查询对象是否为空
        if(mobileMember == null) {//没有这个手机号和邮箱
            return R.error().message("登录失败！");
        }

        //判断密码
        //加密方式 MD5
        if(!MD5.encrypt(password).equals(mobileMember.getPassword())) {
            return R.error().message("登录失败！");
        }

        //登录成功
        //生成token字符串，使用jwt工具类
        String jwtToken = JwtUtils.getJwtToken(mobileMember.getId(), mobileMember.getName());
        redisTemplate.opsForValue().set("jwtToken",jwtToken,1, TimeUnit.HOURS);

        System.out.println("jwt为："+jwtToken);

        return R.ok().data("jwtToken",jwtToken);
    }

    @Override
    public R getMemberInfo(HttpServletRequest request) {
        String jwtToken = request.getHeader("token");
        String Token = redisTemplate.opsForValue().get("jwtToken");

        System.out.println("现在redis中保存的jwt："+Token);
        System.out.println("前端传来的jwt："+jwtToken);

        if (!Token.equals(jwtToken))
            return R.error().message("登录失败，登录信息已过期！");

        //调用jwt工具类的方法。根据request对象获取头信息，返回用户id
        String memberId = JwtUtils.getMemberIdByJwtToken(request);

        //查询数据库根据用户id获取用户信息
        User member = baseMapper.selectById(memberId);

        return R.ok().data("userInfo",member);
    }

    private boolean sendQQMail(String email, String code) {
        if(StringUtils.isEmpty(email)) return false;
        try {
            System.out.println("将要发送邮件到："+email);
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message);
            helper.setFrom(from);
            helper.setTo(email);
            helper.setSubject("会员注册");

            helper.setText("您的注册码为："+ code+"，请在及时填写！有效时长为一分钟！来自在线书店网站",true);
            mailSender.send(helper.getMimeMessage());
            System.out.println("注册码为:"+code);
        } catch (javax.mail.MessagingException e) {
            System.out.println("邮箱发送失败！");
            e.printStackTrace();
        }
        return true;

    }
}
